module Fetch (

    input             clock ,
    input             reset ,
    
    // Execute
    input             ex_if_stall,

    // Forwarding
    input             fw_if_id_stall,

    // Decode
    output reg [31:0] if_id_proximopc,
    output reg [31:0] if_id_instrucao,
    input             id_if_selfontepc,
    input      [31:0] id_if_rega,
    input      [31:0] id_if_pcimd2ext,
    input      [31:0] id_if_pcindex,
    input       [1:0] id_if_seltipopc,

    // Memory Controller
    output            if_mc_en,
    output     [31:0] if_mc_addr,
    input      [31:0] mc_if_data

) ;

    reg [31:0] pc;
	reg  [0:0] reg_if_mc_en ;

	assign if_mc_en = reg_if_mc_en ;
	// Repassa o endereco do pc para o MemController.
	assign if_mc_addr = pc;
        
    // Zera os registradores do Fetch.
    always @(negedge(reset)) begin
        
        pc = 32'b0;
        if_id_proximopc = 32'b0;
        if_id_instrucao = 32'b0;
		reg_if_mc_en = 1'b0 ;

    end
    
    // Ações que dependem do clock.
	always@(negedge(clock)) begin

		// Procedimentos para Forwarding. Valores de if_id_proximopc
		// nao podem ser alterados caso o sinal seja 1.
		if( !fw_if_id_stall ) begin

			// Procedimentos para a ocorrencia de um stall.
			if(ex_if_stall) begin
				if_id_proximopc = pc;
				if_id_instrucao = 32'b0;

			end 
			// Trata o caso em que nao existe Forwarding ou stall.
			else begin

				// Recupera a próxima instrucao.
				// Habilita o MemController para buscar a instrucao.
				reg_if_mc_en = 1'b1;
				// Repassa a instrucao para o Decoder.
				if_id_instrucao = mc_if_data;

				// Escolhe qual valor do PC atualizar para recolher 
				// a proxima instrucao.
				if(id_if_selfontepc) begin 

					if(id_if_seltipopc == 0) begin
						pc = id_if_pcimd2ext;
					end
					if(id_if_seltipopc == 1) begin
					 	pc = id_if_rega; 
					end
					if(id_if_seltipopc == 2) begin
						pc = id_if_pcindex;
					end
					if(id_if_seltipopc == 3) begin
						pc = 32'b00000000000000000000000001000000; // 32'd64
					end
				end
				else begin
					pc = pc + 4;
				end
                if_id_proximopc = pc;
			end
		end 
	end

	always @(negedge(clock)) begin
		reg_if_mc_en = 1'b0;
	end

endmodule
